home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / mkproto.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  6KB  |  243 lines

  1. /* mkproto - make an mkfs prototype    Author: Andrew Cagney */
  2.  
  3. /* Submitted by: cagney@chook.ua.oz (Andrew Cagney - aka Noid) */
  4.  
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <limits.h>
  8. #include <dirent.h>
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11.  
  12. /* The default values for the prototype file */
  13. #define DEF_UID        2    /* bin */
  14. #define DEF_GID        1    /* daemon group */
  15. #define DEF_PROT    0555    /* a=re */
  16. #define DEF_BLOCKS    360
  17. #define DEF_INODES    63
  18. #define DEF_INDENTSTR    "\t"
  19.  
  20. #define major(x) ( (x>>8) & 0377)
  21. #define minor(x) (x & 0377)
  22.  
  23. /* Globals. */
  24. int count, origlen, tabs;
  25. int gid, uid, prot, same_uid, same_gid, same_prot, blocks, inodes;
  26. int block_given, inode_given, dprot;
  27. char *indentstr;
  28. char *proto_file, *top;
  29. FILE *outfile;
  30.  
  31. /* For getopt. */
  32. extern int getopt();
  33. extern int optind;
  34. extern char *optarg;
  35.  
  36. main(argc, argv)
  37. int argc;
  38. char *argv[];
  39. {
  40.   int i;
  41.   register char *ptr;        /* Ptr to *argv in use */
  42.   char *dir;
  43.   struct stat st;
  44.   char op;
  45.  
  46.   gid = DEF_GID;
  47.   uid = DEF_UID;
  48.   prot = DEF_PROT;
  49.   blocks = DEF_BLOCKS;
  50.   inodes = DEF_INODES;
  51.   indentstr = DEF_INDENTSTR;
  52.   inode_given = 0;
  53.   block_given = 0;
  54.   top = 0;
  55.   same_uid = 0;
  56.   same_gid = 0;
  57.   same_prot = 0;
  58.   while ((op = getopt(argc, argv, "b:g:i:p:t:u:d:s")) != EOF) {
  59.     switch (op) {
  60.         case 'b':
  61.         blocks = atoi(optarg);
  62.         block_given = 1;
  63.         break;
  64.         case 'g':
  65.         gid = atoi(optarg);
  66.         if (gid == 0) usage(argv[0]);
  67.         same_gid = 0;
  68.         break;
  69.         case 'i':
  70.         inodes = atoi(optarg);
  71.         inode_given = 1;
  72.         break;
  73.         case 'p':
  74.         sscanf(optarg, "%o", &prot);
  75.         if (prot == 0) usage(argv[0]);
  76.         same_prot = 0;
  77.         break;
  78.         case 's':
  79.         same_prot = 1;
  80.         same_uid = 1;
  81.         same_gid = 1;
  82.         break;
  83.         case 't':    top = optarg;    break;
  84.         case 'u':
  85.         uid = atoi(optarg);
  86.         if (uid == 0) usage(argv[0]);
  87.         same_uid = 0;
  88.         break;
  89.         case 'd':    indentstr = optarg;    break;
  90.         default:        /* Illegal options */
  91.         usage(argv[0]);
  92.     }
  93.   }
  94.  
  95.   if (optind >= argc) {
  96.     usage(argv[0]);
  97.   } else {
  98.     dir = argv[optind];
  99.     optind++;
  100.     proto_file = argv[optind];
  101.   }
  102.   if (!top) top = dir;
  103.   open_outfile();
  104.   if (block_given && !inode_given) inodes = (blocks / 3) + 8;
  105.   if (!block_given && inode_given) usage(argv[0]);
  106.   count = 1;
  107.   tabs = 0;
  108.   origlen = strlen(dir);
  109.  
  110.   /* Check that it really is a directory */
  111.   stat(dir, &st);
  112.   if ((st.st_mode & S_IFMT) != S_IFDIR) {
  113.     fprintf(stderr, "mkproto: %s must be a directory\n", dir);
  114.     usage(argv[0]);
  115.   }
  116.   fprintf(outfile, "boot\n%d %d\n", blocks, inodes);
  117.   display_attrib("", &st);
  118.   fprintf(outfile, "\n");
  119.   descend(dir);
  120.   fprintf(outfile, "$\n");
  121. }
  122.  
  123. /* Output the prototype spec for this directory. */
  124. descend(dirname)
  125. char *dirname;
  126. {
  127.   struct dirent *dp;
  128.   DIR *dirp;
  129.   char *bs, *name, *newdir, *temp, *tempend;
  130.   int i;
  131.   struct stat st;
  132.   unsigned short mode;
  133.  
  134.   dirp = opendir(dirname);
  135.   if (dirp == NULL) {
  136.     fprintf(stderr, "unable to open directory %s\n", dirname);
  137.     return;
  138.   }
  139.   tabs++;
  140.   temp = (char *) malloc(sizeof(char) * strlen(dirname) +1 + PATH_MAX);
  141.   strcpy(temp, dirname);
  142.   strcat(temp, "/");
  143.   tempend = &temp[strlen(temp)];
  144.  
  145.   for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
  146.     name = dp->d_name;
  147.  
  148.     count++;
  149.     strcpy(tempend, name);
  150.  
  151.     if (stat(temp, &st) == -1) {
  152.         fprintf(stderr, "cant get status of '%s' \n", temp);
  153.         continue;
  154.     }
  155.     if (name[0] == '.' && (name[1] == 0 || name[1] == '.' && name[2] == 0))
  156.         continue;
  157.  
  158.     display_attrib(name, &st);
  159.  
  160.     mode = st.st_mode & S_IFMT;
  161.     if (mode == S_IFDIR) {
  162.         fprintf(outfile, "\n");
  163.         descend(temp);
  164.         for (i = 0; i < tabs; i++) {
  165.             fprintf(outfile, indentstr);
  166.         }
  167.         fprintf(outfile, "$\n");
  168.         continue;
  169.     }
  170.     if (mode == S_IFBLK || mode == S_IFCHR) {
  171.         fprintf(outfile, " %d %d\n", major(st.st_rdev), minor(st.st_rdev));
  172.         continue;
  173.     }
  174.     if (mode == S_IFREG) {
  175.         i = origlen;
  176.         fprintf(outfile, "%s%s", indentstr, top);
  177.         while (temp[i] != '\0') {
  178.             fputc(temp[i], outfile);
  179.             i++;
  180.         }
  181.         fprintf(outfile, "\n");
  182.         continue;
  183.     }
  184.     fprintf(outfile, " /dev/null");
  185.     fprintf(stderr,"File\n\t%s\n has an invalid mode, made empty.\n",temp);
  186.   }
  187.   closedir(dirp);
  188.   free(temp);
  189.   tabs--;
  190. }
  191.  
  192.  
  193. display_attrib(name, st)
  194. char *name;
  195. struct stat *st;
  196. {
  197. /* Output the specification for a single file */
  198.  
  199.   int i;
  200.  
  201.   if (same_uid) uid = st->st_uid;
  202.   if (same_gid) gid = st->st_gid;
  203.   if (same_prot)
  204.     prot = st->st_mode & 0777;    /***** This one is a bit shady *****/
  205.   for (i = 0; i < tabs; i++) fprintf(outfile, indentstr);
  206.   fprintf(outfile, "%s%s%c%c%c%3o %d %d",
  207.     name,
  208.     *name == '\0' ? "" : indentstr,    /* stop the tab for a null name */
  209.     (st->st_mode & S_IFMT) == S_IFDIR ? 'd' :
  210.     (st->st_mode & S_IFMT) == S_IFCHR ? 'c' :
  211.     (st->st_mode & S_IFMT) == S_IFBLK ? 'b' :
  212.     '-',            /* file type */
  213.     (st->st_mode & S_ISUID) ? 'u' : '-',    /* set uid */
  214.     (st->st_mode & S_ISGID) ? 'g' : '-',    /* set gid */
  215.     prot,
  216.     uid,
  217.     gid);
  218. }
  219.  
  220. usage(binname)
  221. char *binname;
  222. {
  223.   fprintf(stderr, "Usage: %s [options] source_directory [prototype_file]\n", binname);
  224.   fprintf(stderr, "options:\n");
  225.   fprintf(stderr, "   -b n\t\t file system size is n blocks (default %d)\n", DEF_BLOCKS);
  226.   fprintf(stderr, "   -d STRING\t define the indentation characters (default %s)\n", "(none)");
  227.   fprintf(stderr, "   -g n\t\t use n as the gid on all files (default %d)\n", DEF_GID);
  228.   fprintf(stderr, "   -i n\t\t file system gets n i-nodes (default %d)\n", DEF_INODES);
  229.   fprintf(stderr, "   -p nnn\t use nnn (octal) as mode on all files (default %o)\n", DEF_PROT);
  230.   fprintf(stderr, "   -s  \t\t use the same uid, gid and mode as originals have\n");
  231.   fprintf(stderr, "   -t ROOT\t inital path prefix for each entry\n");
  232.   fprintf(stderr, "   -u n\t\t use nnn as the uid on all files (default %d)\n", DEF_UID);
  233.   exit(1);
  234. }
  235.  
  236. open_outfile()
  237. {
  238.   if (proto_file == NULL)
  239.     outfile = stdout;
  240.   else if ((outfile = fopen(proto_file, "w")) == NULL)
  241.     fprintf(stderr, "Cannot create %s\n ", proto_file);
  242. }
  243.